/****************************************************************************
*                                                                           *
* Copyright (c) Ionescu M. Marius. All rights reserved(2010).               *
*                                                                           *
****************************************************************************/

// (c) Copyright Romanian Software Company.
// Last Change: 22.10.2009 - by Ionescu Marius.
// All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Collections;
using System.Data;

namespace NS_Controls
{
	public class DropDownField : BoundField
	{
		#region Properties
		public string ListDataTextField
		{
			get
			{
				object val = this.ViewState["ListDataTextField"];
				if (null == val)
				{
					return String.Empty;
				}

				return (string)val;
			}
			set
			{
				if (0 != String.CompareOrdinal(value, this.ListDataTextField))
				{
					this.ViewState["ListDataTextField"] = value;
					base.OnFieldChanged();
				}
			}
		}

		public string ListDataValueField
		{
			get
			{
				object val = this.ViewState["ListDataValueField"];
				if (null == val)
				{
					return String.Empty;
				}

				return (string)val;
			}
			set
			{
				if (0 != String.CompareOrdinal(value, this.ListDataValueField))
				{
					this.ViewState["ListDataValueField"] = value;
					base.OnFieldChanged();
				}
			}
		}

		[IDReferenceProperty(typeof(DataSourceControl)), Themeable(false)]
		public string ListDataSourceID
		{
			get
			{
				object val = this.ViewState["ListDataSourceID"];
				if (null == val)
				{
					return String.Empty;
				}

				return (string)val;
			}
			set
			{
				if (0 != String.CompareOrdinal(value, this.ListDataSourceID))
				{
					this.ViewState["ListDataSourceID"] = value;
					base.OnFieldChanged();
				}
			}
		}

		public string ListDataSourceSessionDataSetKey
		{
			get
			{
				object val = this.ViewState["ListDataSourceSessionDataSetKey"];
				if (null == val)
				{
					return String.Empty;
				}

				return (string)val;
			}
			set
			{
				if (0 != String.CompareOrdinal(value, this.ListDataSourceSessionDataSetKey))
				{
					this.ViewState["ListDataSourceSessionDataSetKey"] = value;
					base.OnFieldChanged();
				}
			}
		}

		public string ListDataSourceSessionTableKey
		{
			get
			{
				object val = this.ViewState["ListDataSourceSessionTableKey"];
				if (null == val)
				{
					return String.Empty;
				}

				return (string)val;
			}
			set
			{
				if (0 != String.CompareOrdinal(value, this.ListDataSourceSessionTableKey))
				{
					this.ViewState["ListDataSourceSessionTableKey"] = value;
					base.OnFieldChanged();
				}
			}
		}

		private DataView ListDataSource
		{
			get
			{
				if (this.Control.Page.Session[this.ListDataSourceSessionDataSetKey] == null)
					throw new Exception("Set ListDataSourceSessionDataSetKey and the DataView on the session.");

				return ((DataSet)this.Control.Page.Session[this.ListDataSourceSessionDataSetKey]).Tables[Convert.ToInt32(this.ListDataSourceSessionTableKey)].DefaultView;
			}
		}

		public DataView dataViewSource
		{
			get { return (DataView)(this.ViewState["dataViewSource"] ?? new DataView()); }
			set { this.ViewState["dataViewSource"] = value; }
		}

		#endregion

		public DropDownField() : base() { }
		private string specifier = null;
		public DropDownField(string data) : base() { specifier = data; }

		protected override object GetDesignTimeValue()
		{
			return 0;
		}

		protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
		{
			if (!this.ReadOnly && (0 != (rowState & DataControlRowState.Insert)))
			{
				DropDownList ddl = new DropDownList();
				ddl.ID = "ddl_i" + (specifier ?? "");
				ddl.ToolTip = this.HeaderText;
				ddl.BackColor = System.Drawing.Color.Snow;

				//ddl.Style.Add("width", "200px");

				ddl.DataTextField = this.ListDataTextField;
				ddl.DataValueField = this.ListDataValueField;
				ddl.DataSource = this.dataViewSource;
				ddl.DataBind();

				cell.Controls.Add(ddl);
			}

			else if (!this.ReadOnly && (0 != (rowState & DataControlRowState.Edit)))
			{
				DropDownList ddl = new DropDownList();
				ddl.ID = "ddl_e" + (specifier ?? "");
				ddl.ToolTip = this.HeaderText;
				ddl.BackColor = System.Drawing.Color.Snow;
				//ddl.Style.Add("max-width", "200px");

				if (!String.IsNullOrEmpty(this.DataField) && 0 != (rowState & DataControlRowState.Edit))
				{
					ddl.DataBinding += new EventHandler(HandleDataBinding);
					ddl.DataBound += new EventHandler(HandleDataBound);
				}

				cell.Controls.Add(ddl);
			}

			else if (!String.IsNullOrEmpty(this.DataField))
			{
				Label lbl = new Label();
				lbl.ID = "lbl_v" + (specifier ?? "");
				lbl.DataBinding += new EventHandler(HandleDataBinding);
				cell.Controls.Add(lbl);
			}
		}

		public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
		{
			if (cell.HasControls() && cell.Controls[0] is DropDownList)
			{
				DropDownList ddl = (DropDownList)cell.Controls[0];
				dictionary[this.DataField] = String.IsNullOrEmpty(ddl.SelectedValue) ? null : ddl.SelectedValue;
			}
		}

		/// <summary>
		/// Callback from the datasourceview.
		/// </summary>
		/// <param name="data"></param>
		private void DataSourceCallback(IEnumerable data)
		{
			this.data = data;
		}

		private IEnumerable data = null;

		private void HandleDataBinding(object sender, EventArgs e)
		{
			Control ctrl = (Control)sender;

			string val = null;
			if (ctrl.NamingContainer != null)
			{
				object rawVal = GetValue(ctrl.NamingContainer);
				val = (null == rawVal ? null : rawVal.ToString());
			}

			if (null == data)
			{
				if (!String.IsNullOrEmpty(this.ListDataSourceID))
				{// use DataSourceID
					//Cache the data from the DataSourceControl, so that we only get the data once.  If 
					//we just set the DataSourceID on the dropdown, the select command would get called 
					//once for each row.
					DataSourceControl dsc = Tools.RecursiveFindControl(this.Control.NamingContainer, this.ListDataSourceID) as DataSourceControl;
					if (null != dsc)
					{
						DataSourceView dsv = ((IDataSource)dsc).GetView("DefaultView");
						dsv.Select(DataSourceSelectArguments.Empty, new DataSourceViewSelectCallback(this.DataSourceCallback));
					}
				}
				if (!String.IsNullOrEmpty(this.ListDataSourceSessionDataSetKey) && !String.IsNullOrEmpty(this.ListDataSourceSessionTableKey))
				{// use DataView on session
					if (this.Control != null)
						this.data = this.ListDataSource;
				}
			}

			if (ctrl is DropDownList)
			{
				DropDownList ddl = (DropDownList)ctrl;
				ddl.DataTextField = this.ListDataTextField;
				ddl.DataValueField = this.ListDataValueField;
				ddl.DataSource = this.data;
				if (e == null)
					ddl.DataBind();
			}
			else if (ctrl is Label)
			{
				Label lbl = (Label)ctrl;

				DropDownList temp = new DropDownList();
				temp.DataTextField = this.ListDataTextField;
				temp.DataValueField = this.ListDataValueField;
				temp.DataSource = this.data;
				temp.Visible = false;

				lbl.Controls.Add(temp);
				temp.DataBind();

				lbl.Text = String.Empty;
				foreach (ListItem li in temp.Items)
				{
					if (0 == String.Compare(li.Value, val))
						lbl.Text = li.Text;
				}
			}
		}

		private void HandleDataBound(object sender, EventArgs e)
		{
			Control ctrl = (Control)sender;
			string val = null;
			if (ctrl.NamingContainer != null)
				val = GetValue(ctrl.NamingContainer).ToString();

			DropDownList ddl = ctrl as DropDownList;
			if (null != ddl)
			{
				//make sure the appropriate value is selected
				ListItem li = ddl.Items.FindByValue(val);
				if (null != li)
				{
					li.Selected = true;
				}
			}
		}
	}
}
